import React, { Fragment, FC, memo, useState, useEffect, useRef, useCallback, useMemo } from 'react'

interface ResultDataType {
  code: 0 | -1
  list: { id: number; title: string; count: number; price: number }[]
}

const createData = () => {
  return new Promise<ResultDataType>((resolve, reject) => {
    resolve({
      code: 0,
      list: [
        {
          id: 1,
          title: '测试1',
          count: 1,
          price: 10,
        },
        {
          id: 2,
          title: '测试2',
          count: 1,
          price: 20,
        },
        {
          id: 3,
          title: '测试3',
          count: 3,
          price: 10,
        },
        {
          id: 4,
          title: '测试4',
          count: 1,
          price: 20,
        },
        {
          id: 5,
          title: '测试5',
          count: 5,
          price: 10,
        },
      ],
    })
  })
}

/**
 * todoList
 * 1. todoControl
 * 2. todoView
 *
 * - 添加
 * - 切换
 * - 删除
 */

interface TodoListProps {
  onClick(params: TodoItem): void
}
interface TodoItem {
  id: number
  status: boolean
  value: string
}

// 子
const TodoControl: FC<TodoListProps> = memo((props) => {
  console.log('TodoControl----')
  const { onClick } = props
  const inputRef = useRef<HTMLInputElement | null>(null)

  const handleClick = () => {
    if (inputRef.current) {
      onClick &&
        onClick({
          id: Date.now(),
          status: false,
          value: inputRef.current.value,
        })
      inputRef.current.value = ''
    }
  }

  return (
    <div>
      TodoControl
      <input ref={inputRef} type="text" /> <button onClick={handleClick}>添加</button>
    </div>
  )
})

interface TodoView {
  list: TodoItem[]
  toggleClick(item: TodoItem): void
  removeClick(item: TodoItem): void
}
// 子
const TodoView: FC<TodoView> = memo((props) => {
  const { list, toggleClick, removeClick } = props
  console.log('TodoView----')

  return (
    <ul>
      {list.map((item) => {
        return (
          <Fragment key={item.id}>
            <li className={item.status ? 'active' : ''} key={item.id}>
              {item.value}
            </li>
            <span onClick={() => toggleClick(item)}>切换</span>
            <span onClick={() => removeClick(item)}>删除</span>
            <hr />
          </Fragment>
        )
      })}
    </ul>
  )
})

const FooBar = memo((props: any) => {
  const { onClick, count, totalPrice } = props
  console.log(props, '------------------------foobar')
  return (
    <div>
      <h1 onClick={onClick}>
        {count}:{totalPrice}:Foobar-button子组件
      </h1>
    </div>
  )
})

//

let myPage = 0
// 父组件
const TodoList = () => {
  const [todo, setTodo] = useState<TodoItem[]>([])
  const [count, setCount] = useState(0)
  const [list, setList] = useState<any[]>([])

  const page = useRef<number>(0)

  // useMemo 类似于vue的计算属性， 优化计算逻辑，他有返回值,会参与页面渲染阶段
  // useEffect 会等到render 结束才执行
  // useMemo不会，逻辑改变，页面渲染，参与渲染（useMemo会比useEffect执行的时机要早）
  const totalPrice = useMemo(() => {
    console.log('list-----------------', list)
    return list.reduce((num, item) => {
      return num + item.count * item.price
    }, 0)
  }, [list])

  // 处理副作用
  useEffect(() => {
    const fetchList = async () => {
      const result = await createData()
      console.log('result:', result.list)
      setList(result.list)
    }
    fetchList()
  }, [])

  // 添加函数
  const handleAddTodoItem = (item: TodoItem) => {
    setTodo(() => [...todo, item])
  }

  // 切换函数
  const handleToggleClick = useCallback((item: TodoItem) => {
    item.status = !item.status
    console.log(item, 'item')
    setTodo((todo) => [...todo])
  }, [])

  // 删除
  const handleRemoveClick = useCallback(
    (item: TodoItem) => {
      setTodo(() => todo.filter((v) => v.id !== item.id))
    },
    [todo]
  )

  // useCallback 可以优化函数的返回具柄 第二个参数可以帮助我们去更新想要的值
  const onClick = useCallback(() => {
    console.log('onClick')
    setCount(() => count + 1)
  }, [count])

  useEffect(() => {
    console.log('count', count)
  }, [count])

  // render 是一个纯函数
  return (
    <div>
      <button
        onClick={() => {
          myPage++
          page.current++
          console.log('myPage:', myPage, 'page:', page.current, 'page')
        }}
      >
        更新useRef数据
      </button>

      <hr />
      <h1
        onClick={() => {
          setList(() => [
            ...list,
            {
              id: Date.now(),
              title: '测试1',
              count: 1,
              price: 10,
            },
          ])
        }}
      >
        {totalPrice}
      </h1>
      {/* <button onClick={onClick}>我是一个测试按钮</button> */}
      <TodoControl onClick={handleAddTodoItem}></TodoControl>
      <TodoView toggleClick={handleToggleClick} removeClick={handleRemoveClick} list={todo}></TodoView>

      <FooBar totalPrice={totalPrice} onClick={onClick} count={count}></FooBar>
      {/* <FooBar count={count}></FooBar> */}
    </div>
  )
}

export default TodoList
